package com.hengpeng.itfints.controller.investInfo;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.common.persist.entity.AbstractEntity.BoolValue;
import com.hengpeng.common.util.MoneyUtil;
import com.hengpeng.common.util.StringHelper;
import com.hengpeng.itfinbase.constants.RespCodeConstants;
import com.hengpeng.itfinbase.constants.RespCodeConstants.CommonCode;
import com.hengpeng.itfinbase.constants.TransCodeConstants;
import com.hengpeng.itfinbase.message.ResponseMessage;
import com.hengpeng.itfinbase.message.partner.InvestBorrowerDetail;
import com.hengpeng.itfinbase.message.partner.InvestInfoRequestMsg;
import com.hengpeng.itfinbase.message.partner.PartnerTransType;
import com.hengpeng.itfinbase.message.partner.QueryBalanceRequest;
import com.hengpeng.itfinbase.message.partner.QueryBalanceResponse;
import com.hengpeng.itfinbase.message.partner.TenderCancleRequest;
import com.hengpeng.itfinbase.message.partner.TenderCancleResponse;
import com.hengpeng.itfinbase.persist.Account;
import com.hengpeng.itfinbase.persist.BorrowInfo;
import com.hengpeng.itfinbase.persist.InvestInfo;
import com.hengpeng.itfinbase.persist.UserInfo;
import com.hengpeng.itfints.constants.PartnerUtil;
import com.hengpeng.itfints.constants.TSConstants;
import com.hengpeng.itfints.controller.BaseController;
import com.hengpeng.itfints.controller.investInfo.vo.InvestInfoVo;
import com.hengpeng.itfints.tools.JsonUtils;
import com.hengpeng.itfints.tools.PageUtil;
import com.hengpeng.itfints.vo.MemberSession;

/**
 * <pre>
 * 投标控制器
 * </pre>
 * @author weiyuan
 * @version 1.0, 2015年5月28日
 */
@Controller
@RequestMapping("/investInfo")
public class InvestInfoController extends BaseController
{
	/**
	 * <pre>
	 * 我的投资记录列表
	 * </pre>
	 * @param map
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/myInvestList")
	public String myInvestList(ModelMap map, HttpServletRequest request, String curPage,
			InvestInfo.InvestStatus investInfoStatus)
	{
		UserInfo m = getSessionMember(request).getUser();

		List<InvestInfoVo> dataList = serviceFactory.getInvestInfoService().queryMyInvestList(m.getId(),
				investInfoStatus, null);
		int currentPage = (!StringHelper.isEmpty(curPage) && curPage != null ? Integer.parseInt(curPage) : 1);
		PageUtil pUtil = new PageUtil(10, dataList.size(), currentPage);

		Account account = serviceFactory.getAccountService().getAccount(m.getId());
		map.put("myInvestList", dataList);
		map.put("account", account);
		map.put("investInfoStatus", investInfoStatus == null ? InvestInfo.InvestStatus.LOANED : investInfoStatus);
		map.put("PageUtil", pUtil);
		return "/page/account/investlog/index.jsp";
	}

	/**
	 * <pre>
	 * 根据日历查看回款情况
	 * </pre>
	 * @param map
	 * @param request
	 * @param page
	 * @param investInfoStatus
	 * @param arrivalTime
	 * @return
	 */
	@RequestMapping(value = "/calInvestInfo")
	public String calInvestInfo(ModelMap map, HttpServletRequest request, String arrivalTime)
	{
		UserInfo m = getSessionMember(request).getUser();
		List<InvestInfoVo> dataList = serviceFactory.getInvestInfoService().queryMyInvestList(m.getId(),
				InvestInfo.InvestStatus.LOANED, arrivalTime);
		map.put("myInvestList", dataList);
		return "/page/account/investlog/calInvestinfo.jsp";
	}

	/**
	 * <pre>
		 校验事项：
		  1,投资人账户中必须有足够的资金进行投资。
		  2,借款标的状态必须是：筹款中状态。
		  3,投资金额必须在标的的最大投资金额和最小投资金额之间。
		  4,校验投资金额是否已经超过剩余借款额度
		 投资前操作：
		  1,投资调用投资接口前，先占据投资额度(更新标的信息表中已募集金额,和已募集人数)
		  2,设定投资支付时间限制，若超过时间限制还没有支付完成则释放投资额度。
		  3,超过支付时间限制的投标，调用撤标接口。
		  4,生成投资记录信息,状态为：投标中
		 投资接口调用成功后操作：
		  1,更新投资信息状态
		  2,冻结投资人资金信息表中相关资金。
		  3,添加资金流水表相关资金冻结流水。
		  4,更新标的信息表中的已募集金额,已募集人数。
		  5,判断标的是否已经金额达到募集金额，如果达到募集金额则设置标的状态为：募集结束
		 投资接口调用失败后操作：
		  1,释放投资额度
		  2,更新投标信息状态为：失败
		 投标实时返回和回调接口都需实现
		</pre>
	 * @param map
	 * @param request
	 * @param borrowInfoId 标的id
	 * @param investMoney 投资金额
	 * @return
	 */
	@RequestMapping(value = "/doInvest")
	@ResponseBody
	public ServiceResult<ResponseMessage> doInvest(ModelMap map, HttpServletRequest request, String borrowInfoId,
			Long investMoney)
	{
		ServiceResult<ResponseMessage> result = new ServiceResult<ResponseMessage>();
		ResponseMessage response = new ResponseMessage();
		BorrowInfo borrowInfo = serviceFactory.getBorrowInfoService().getBorrowInfo(Long.parseLong(borrowInfoId),
				BorrowInfo.BorrowStatus.RAISE);
		MemberSession member = (MemberSession) request.getSession().getAttribute(TSConstants.CLIENT_SESSION_MEMBER);
		if (member == null)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("请先登录");
			result.setReturnValue(response);
			return result;
		}
		if (borrowInfo == null)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("标的不存在,或标的状态异常");
			result.setReturnValue(response);
			return result;
		}
		if (investMoney < (borrowInfo.getMinInvest() / 100) || investMoney > (borrowInfo.getMaxInvest() / 100))
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("投标金额不能小于最小投资额,并且不能大于最大投资额");
			result.setReturnValue(response);
			return result;
		}
		if ((investMoney * 100 - borrowInfo.getMinInvest()) % borrowInfo.getIncMoney() != 0)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("最小投标为:" + MoneyUtil.convertFenToYuan(borrowInfo.getMinInvest()) + "，增量金额必须为:"
					+ MoneyUtil.convertFenToYuan(borrowInfo.getIncMoney()) + "的整数倍");
			result.setReturnValue(response);
			return result;
		}
		if ((borrowInfo.getRaiseMoney() + investMoney * 100) > borrowInfo.getBorrowMoney())
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("投资额度已大于剩余融资额度");
			result.setReturnValue(response);
			return result;
		}
		if (member.getUser() == null)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("当前用户信息异常,请重新登录");
			result.setReturnValue(response);
			return result;
		}
		if (member.getUser().getIsInvestor() == BoolValue.NO)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("对不起,您不是投资人角色");
			result.setReturnValue(response);
			return result;
		}
		if (member.getUser().getId().equals(borrowInfo.getBorrowUserId()))
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("对不起,您不能投资自己的借款标");
			result.setReturnValue(response);
			return result;
		}
		if (StringHelper.isEmpty(member.getUser().getTrustAccountId())) {
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("请您先开通托管账户");
			result.setReturnValue(response);
			return result;
		}
		try
		{
			QueryBalanceRequest balanceRequest = new QueryBalanceRequest();
			balanceRequest.setUserId(member.getUser().getId());
			balanceRequest.setUsrCustId(member.getUser().getTrustAccountId());
			balanceRequest.setPartnerTransType(PartnerTransType.QueryBalanceBg);
			balanceRequest.setTransType(TransCodeConstants.PartnerTransCode.REQUEST);
			QueryBalanceResponse balance = (QueryBalanceResponse) serviceFactory.getProtFactory().remoteTrans(
					balanceRequest);
			if (CommonCode.TRANS_SUC.equals(balance.getRespCode()))
			{
				if (investMoney.doubleValue() > (Double.parseDouble(balance.getAvlBal().replaceAll(",", ""))))
				{
					result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
					result.setMessage("余额不足!");
					result.setReturnValue(response);
					return result;
				}
			}
			else
			{
				result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
				result.setMessage("投标失败,原因如下：" + balance.getRespDesc());
				result.setReturnValue(response);
				return result;
			}
		}
		catch (Exception e)
		{
			result.setCode(RespCodeConstants.CommonCode.TRANS_FAIL);
			result.setMessage("余额查询失败!具体信息如下:" + e.getMessage());
			result.setReturnValue(response);
			return result;
		}
		InvestInfoRequestMsg reqMsg = new InvestInfoRequestMsg();
		List<InvestBorrowerDetail> borrowerDetails = new ArrayList<InvestBorrowerDetail>();
		InvestBorrowerDetail borrowerDetail = new InvestBorrowerDetail();
		borrowerDetail.setBorrowerCustId(borrowInfo.getBorrowUserTrustAccountId());
		borrowerDetail.setBorrowerAmt(MoneyUtil.convertFenToYuan(investMoney * 100));
		borrowerDetail.setBorrowerRate(TSConstants.CHAR_ONE);
		borrowerDetail.setProId(borrowInfo.getId().toString());
		borrowerDetails.add(borrowerDetail);
		reqMsg.setBorrowerDetails(JsonUtils.createGson().create().toJson(borrowerDetails));
		reqMsg.setTransAmt(String.valueOf(investMoney * 100));
		reqMsg.setUsrCustId(member.getUser().getTrustAccountId());
		reqMsg.setIsFreeze(TSConstants.CHAR_YES);
		reqMsg.setInvestUserName(member.getUser().getUserName());
		reqMsg.setInvestUserId(member.getUser().getId().toString());
		reqMsg.setBorrowInfoId(borrowInfo.getId().toString());
		reqMsg.setBorrowName(borrowInfo.getBorrowName());
		reqMsg.setPartnerTransType(PartnerTransType.InitiativeTender);
		reqMsg.setTransType(TransCodeConstants.PartnerTransCode.REQUEST);
		response = (ResponseMessage) serviceFactory.getProtFactory().remoteTrans(reqMsg);
		result.setCode(RespCodeConstants.CommonCode.TRANS_SUC);
		result.setMessage(RespCodeConstants.CommonCode.TRANS_SUC_MSG);
		result.setReturnValue(response);
		result.setReturnObject(PartnerUtil.isTrustPattern());
		return result;
	}

	/**
	 * <pre>
	 * 撤标操作
	 * </pre>
	 * @param map
	 * @param request
	 * @param inverstId
	 * @return
	 */
	@RequestMapping(value = "/cancelInvest")
	@ResponseBody
	public ServiceResult<ResponseMessage> cancelInvest(ModelMap map, HttpServletRequest request, Long inverstId)
	{
		ServiceResult<ResponseMessage> result = new ServiceResult<ResponseMessage>();
		ResponseMessage response = new ResponseMessage();
		MemberSession member = (MemberSession) request.getSession().getAttribute(TSConstants.CLIENT_SESSION_MEMBER);
		if (member == null)
		{
			response.setOrderFormContent("撤标失败,原因如下：请先登录");
			result.setReturnValue(response);
			return result;
		}

		try
		{
			TenderCancleRequest tenderCancleRequest = new TenderCancleRequest();
			tenderCancleRequest.setUsrCustId(member.getUser().getTrustAccountId());
			tenderCancleRequest.setOrdId(String.valueOf(inverstId));
			tenderCancleRequest.setPartnerTransType(PartnerTransType.TenderCancle);
			tenderCancleRequest.setTransType(TransCodeConstants.PartnerTransCode.REQUEST);
			TenderCancleResponse tenderCancleResponse = (TenderCancleResponse) serviceFactory.getProtFactory()
					.remoteTrans(tenderCancleRequest);
			response.setOrderFormContent(tenderCancleResponse.getRespDesc());
			result.setReturnValue(response);
			return result;
		}
		catch (Exception e)
		{
			response.setOrderFormContent("撤标失败,原因如下:" + e.getMessage());
			result.setReturnValue(response);
			return result;
		}

	}
}
